﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COFE.Core;
using COFE.Core.Lister;
using NUnit.Framework;

namespace COFE.Core.Profile
{
    /// <summary>
    /// Implements IVolume, provide information about a IDirectoryLister.
    /// </summary>
    public class Volume : IVolume
    {
        private IDirectoryLister _cacheDirectoryLister = null;

        public string FactoryKey { get; private set; }
        public string ListerKey { get; private set; }        
        public IDirectoryLister DirectoryLister { get; protected set; }
        public IDirectoryLister CacheDirectoryLister
        {
            get
            {
                return _cacheDirectoryLister == null ? DirectoryLister :
                    _cacheDirectoryLister;
            }
            protected set { _cacheDirectoryLister = value; }
        }
        public IDirectoryController DirectoryController { get; protected set; }
        public IStreamProvider StreamProvider { get; protected set; }
        public VolumeAccessMode AccessMode { get; protected set; }

        public override string ToString()
        {
            return String.Format("{0}, {1} ({2})", DirectoryLister.ListerKey,
                CacheDirectoryLister.ListerKey, AccessMode);
        }

        public override int GetHashCode()
        {
            return DirectoryLister.ListerKey.GetHashCode();
        }

        public Volume(string factoryKey,             
            IDirectoryLister directoryLister,             
            IDirectoryLister cachedDirectoryLister,
            VolumeAccessMode accessMode)
            : this(factoryKey, directoryLister.ListerKey, accessMode)
        {           
            DirectoryLister = directoryLister;
            CacheDirectoryLister = cachedDirectoryLister == null ? directoryLister : cachedDirectoryLister;
            DirectoryController = directoryLister.CreateController();            
            StreamProvider = directoryLister.CreateStreamProvider();
        }

        public Volume(string factoryKey, string listerKey, VolumeAccessMode defAccessMode, 
            Func<IDirectoryLister, IDirectoryLister> cacheDirectoryListerConstructorFunc,
             string paramString)
            : this(factoryKey, listerKey, defAccessMode)
        {

            Assert.IsTrue(COFEShared.VolumeRegistrar.Factories.ContainsKey(factoryKey), factoryKey + " is not exists.");
            DirectoryLister = COFEShared.VolumeRegistrar.Factories[factoryKey].Construct(listerKey, paramString);
            if (cacheDirectoryListerConstructorFunc != null)
                CacheDirectoryLister = cacheDirectoryListerConstructorFunc(DirectoryLister);
            DirectoryController = DirectoryLister.CreateController();
            StreamProvider = DirectoryLister.CreateStreamProvider();
            FactoryKey = factoryKey;
        }

        public Volume(string factoryKey, string listerKey, VolumeAccessMode accessMode,
             string paramString)
            : this(factoryKey, listerKey, accessMode, null, paramString) { }

        protected Volume(string factoryKey, string listerKey, VolumeAccessMode accessMode)
        {
            AccessMode = accessMode;
            FactoryKey = factoryKey;
            ListerKey = listerKey;
            
        }

    }
}
